package com.futvan.z.framework.util;

import com.futvan.z.framework.common.bean.Code;
import com.futvan.z.framework.common.bean.Result;
import com.futvan.z.framework.core.z;
import com.futvan.z.framework.util.enums.IdType;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;

/**
 * 身份证号工具类
 * @author 42239
 *
 */
public class IDCardUtil {
	public static void main(String[] args) {
		String idno = "21100219830704661X";
		System.out.println(idno.substring(idno.length()-6));
	}
	
	/**
	 * 获取身份证中的信息
	 * @param type
	 * @return
	 */
	public static String getIDCardInfo(String idNo,IdType type) {
		String result = "";
		Result r = vIDCard(idNo);
		if(Code.SUCCESS.equals(r.getCode())) {
			if(IdType.birthday.equals(type)) {
				//生日
				String strYear = idNo.substring(6, 10);// 年份
				String strMonth = idNo.substring(10, 12);// 月份
				String strDay = idNo.substring(12, 14);// 月份
				result = strYear+"-"+strMonth+"-"+strDay;
				
			}else if(IdType.area_code.equals(type)) {
				//地区
				result = idNo.substring(0, 5);
			}
		}
		return result;
	}
	
	/**
	 * 身份证验证
	 * @param idStr
	 * @return
	 */
	public static Result vIDCard(String idStr){
		Result result = new Result();
		if(z.isNotNull(idStr)) {
			String[] wf = { "1", "0", "x", "9", "8", "7", "6", "5", "4", "3", "2"};
			String[] checkCode = { "7", "9", "10", "5", "8", "4", "2", "1", "6", "3", "7", "9", "10", "5", "8", "4", "2" };
			String iDCardNo = "";
			try {
				//判断号码的长度 15位或18位
				if (idStr.length() != 15 && idStr.length() != 18) {
					result.setCode(Code.ERROR);
					result.setMsg("身份证号码长度应该为15位或18位");
				}else {
					if (idStr.length() == 18) {
						iDCardNo = idStr.substring(0, 17);
					} else if (idStr.length() == 15) {
						iDCardNo = idStr.substring(0, 6) + "19" + idStr.substring(6, 15);
					}
					if (MathUtil.isNum(iDCardNo) == false) {
						result.setCode(Code.ERROR);
						result.setMsg("身份证15位号码都应为数字;18位号码除最后一位外,都应为数字");
					}else {
						//判断出生年月
						String strYear = iDCardNo.substring(6, 10);// 年份
						String strMonth = iDCardNo.substring(10, 12);// 月份
						String strDay = iDCardNo.substring(12, 14);// 月份
						if (DateUtil.isDate(strYear + "-" + strMonth + "-" + strDay) == false) {
							result.setCode(Code.ERROR);
							result.setMsg("身份证生日无效");
						}else {
							GregorianCalendar gc = new GregorianCalendar();
							SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd");
							if ((gc.get(Calendar.YEAR) - Integer.parseInt(strYear)) > 150 || (gc.getTime().getTime() - s.parse(strYear + "-" + strMonth + "-" + strDay).getTime()) < 0) {
								result.setCode(Code.ERROR);
								result.setMsg("身份证生日不在有效范围");
							}else {
								if (Integer.parseInt(strMonth) > 12 || Integer.parseInt(strMonth) == 0) {
									result.setCode(Code.ERROR);
									result.setMsg("身份证月份无效");
								}else {
									if (Integer.parseInt(strDay) > 31 || Integer.parseInt(strDay) == 0) {
										result.setCode(Code.ERROR);
										result.setMsg("身份证日期无效");
									}else {
										//判断地区码
										Map<String,String> h = GetAreaCode();
										if (h.get(iDCardNo.substring(0, 4)) == null) {
											result.setCode(Code.ERROR);
											result.setMsg("身份证地区编码错误");
										}else {
											//判断最后一位
											int theLastOne = 0;
											for (int i = 0; i < 17; i++) {
												theLastOne = theLastOne + Integer.parseInt(String.valueOf(iDCardNo.charAt(i))) * Integer.parseInt(checkCode[i]);
											}
											int modValue = theLastOne % 11;
											String strVerifyCode = wf[modValue];
											iDCardNo = iDCardNo + strVerifyCode;
											if (idStr.length() == 18 &&!iDCardNo.toLowerCase().equals(idStr.toLowerCase())) {
												result.setCode(Code.ERROR);
												result.setMsg("身份证验证未通过，号码不是合法身份证号");
											}else {
												result.setCode(Code.SUCCESS);
												result.setMsg("ok");
											}
										}
									}
								}
							}
						}
					}
				}
			}catch (Exception e){
				result.setCode(Code.ERROR);
				result.setMsg(StringUtil.ExceptionToString(e));
			}
		}else {
			result.setCode(Code.ERROR);
			result.setMsg("身份证号不可为空");
		}
		return result;
	}

	/**
	 * 地区代码
	 * @return Hashtable
	 */
	private static Map<String,String> GetAreaCode() {
		Map<String,String> areaCode = new HashMap();
		areaCode.put("1101", "北京市");
		areaCode.put("1201", "天津市");
		areaCode.put("1301", "石家庄市");
		areaCode.put("1302", "唐山市");
		areaCode.put("1303", "秦皇岛市");
		areaCode.put("1304", "邯郸市");
		areaCode.put("1305", "邢台市");
		areaCode.put("1306", "保定市");
		areaCode.put("1307", "张家口市");
		areaCode.put("1308", "承德市");
		areaCode.put("1309", "沧州市");
		areaCode.put("1310", "廊坊市");
		areaCode.put("1311", "衡水市");
		areaCode.put("1401", "太原市");
		areaCode.put("1402", "大同市");
		areaCode.put("1403", "阳泉市");
		areaCode.put("1404", "长治市");
		areaCode.put("1405", "晋城市");
		areaCode.put("1406", "朔州市");
		areaCode.put("1407", "晋中市");
		areaCode.put("1408", "运城市");
		areaCode.put("1409", "忻州市");
		areaCode.put("1410", "临汾市");
		areaCode.put("1411", "吕梁市");
		areaCode.put("1501", "呼和浩特市");
		areaCode.put("1502", "包头市");
		areaCode.put("1503", "乌海市");
		areaCode.put("1504", "赤峰市");
		areaCode.put("1505", "通辽市");
		areaCode.put("1506", "鄂尔多斯市");
		areaCode.put("1507", "呼伦贝尔市");
		areaCode.put("1508", "巴彦淖尔市");
		areaCode.put("1509", "乌兰察布市");
		areaCode.put("1522", "兴安盟");
		areaCode.put("1525", "锡林郭勒盟");
		areaCode.put("1529", "阿拉善盟");
		areaCode.put("2101", "沈阳市");
		areaCode.put("2102", "大连市");
		areaCode.put("2103", "鞍山市");
		areaCode.put("2104", "抚顺市");
		areaCode.put("2105", "本溪市");
		areaCode.put("2106", "丹东市");
		areaCode.put("2107", "锦州市");
		areaCode.put("2108", "营口市");
		areaCode.put("2109", "阜新市");
		areaCode.put("2110", "辽阳市");
		areaCode.put("2111", "盘锦市");
		areaCode.put("2112", "铁岭市");
		areaCode.put("2113", "朝阳市");
		areaCode.put("2114", "葫芦岛市");
		areaCode.put("2201", "长春市");
		areaCode.put("2202", "吉林市");
		areaCode.put("2203", "四平市");
		areaCode.put("2204", "辽源市");
		areaCode.put("2205", "通化市");
		areaCode.put("2206", "白山市");
		areaCode.put("2207", "松原市");
		areaCode.put("2208", "白城市");
		areaCode.put("2224", "延边朝鲜族自治州");
		areaCode.put("2301", "哈尔滨市");
		areaCode.put("2302", "齐齐哈尔市");
		areaCode.put("2303", "鸡西市");
		areaCode.put("2304", "鹤岗市");
		areaCode.put("2305", "双鸭山市");
		areaCode.put("2306", "大庆市");
		areaCode.put("2307", "伊春市");
		areaCode.put("2308", "佳木斯市");
		areaCode.put("2309", "七台河市");
		areaCode.put("2310", "牡丹江市");
		areaCode.put("2311", "黑河市");
		areaCode.put("2312", "绥化市");
		areaCode.put("2327", "大兴安岭地区");
		areaCode.put("3101", "上海市");
		areaCode.put("3201", "南京市");
		areaCode.put("3202", "无锡市");
		areaCode.put("3203", "徐州市");
		areaCode.put("3204", "常州市");
		areaCode.put("3205", "苏州市");
		areaCode.put("3206", "南通市");
		areaCode.put("3207", "连云港市");
		areaCode.put("3208", "淮安市");
		areaCode.put("3209", "盐城市");
		areaCode.put("3210", "扬州市");
		areaCode.put("3211", "镇江市");
		areaCode.put("3212", "泰州市");
		areaCode.put("3213", "宿迁市");
		areaCode.put("3301", "杭州市");
		areaCode.put("3302", "宁波市");
		areaCode.put("3303", "温州市");
		areaCode.put("3304", "嘉兴市");
		areaCode.put("3305", "湖州市");
		areaCode.put("3306", "绍兴市");
		areaCode.put("3307", "金华市");
		areaCode.put("3308", "衢州市");
		areaCode.put("3309", "舟山市");
		areaCode.put("3310", "台州市");
		areaCode.put("3311", "丽水市");
		areaCode.put("3312", "舟山群岛新区");
		areaCode.put("3401", "合肥市");
		areaCode.put("3402", "芜湖市");
		areaCode.put("3403", "蚌埠市");
		areaCode.put("3404", "淮南市");
		areaCode.put("3405", "马鞍山市");
		areaCode.put("3406", "淮北市");
		areaCode.put("3407", "铜陵市");
		areaCode.put("3408", "安庆市");
		areaCode.put("3410", "黄山市");
		areaCode.put("3411", "滁州市");
		areaCode.put("3412", "阜阳市");
		areaCode.put("3413", "宿州市");
		areaCode.put("3415", "六安市");
		areaCode.put("3416", "亳州市");
		areaCode.put("3417", "池州市");
		areaCode.put("3418", "宣城市");
		areaCode.put("3501", "福州市");
		areaCode.put("3502", "厦门市");
		areaCode.put("3503", "莆田市");
		areaCode.put("3504", "三明市");
		areaCode.put("3505", "泉州市");
		areaCode.put("3506", "漳州市");
		areaCode.put("3507", "南平市");
		areaCode.put("3508", "龙岩市");
		areaCode.put("3509", "宁德市");
		areaCode.put("3601", "南昌市");
		areaCode.put("3602", "景德镇市");
		areaCode.put("3603", "萍乡市");
		areaCode.put("3604", "九江市");
		areaCode.put("3605", "新余市");
		areaCode.put("3606", "鹰潭市");
		areaCode.put("3607", "赣州市");
		areaCode.put("3608", "吉安市");
		areaCode.put("3609", "宜春市");
		areaCode.put("3610", "抚州市");
		areaCode.put("3611", "上饶市");
		areaCode.put("3701", "济南市");
		areaCode.put("3702", "青岛市");
		areaCode.put("3703", "淄博市");
		areaCode.put("3704", "枣庄市");
		areaCode.put("3705", "东营市");
		areaCode.put("3706", "烟台市");
		areaCode.put("3707", "潍坊市");
		areaCode.put("3708", "济宁市");
		areaCode.put("3709", "泰安市");
		areaCode.put("3710", "威海市");
		areaCode.put("3711", "日照市");
		areaCode.put("3712", "莱芜市");
		areaCode.put("3713", "临沂市");
		areaCode.put("3714", "德州市");
//		areaCode.put("3715", "聊城市");
		areaCode.put("3716", "滨州市");
		areaCode.put("3717", "菏泽市");
		areaCode.put("4101", "郑州市");
		areaCode.put("4102", "开封市");
		areaCode.put("4103", "洛阳市");
		areaCode.put("4104", "平顶山市");
		areaCode.put("4105", "安阳市");
		areaCode.put("4106", "鹤壁市");
		areaCode.put("4107", "新乡市");
		areaCode.put("4108", "焦作市");
		areaCode.put("4109", "濮阳市");
		areaCode.put("4110", "许昌市");
		areaCode.put("4111", "漯河市");
		areaCode.put("4112", "三门峡市");
		areaCode.put("4113", "南阳市");
		areaCode.put("4114", "商丘市");
		areaCode.put("4115", "信阳市");
		areaCode.put("4116", "周口市");
		areaCode.put("4117", "驻马店市");
		areaCode.put("4190", "济源市");
		areaCode.put("4201", "武汉市");
		areaCode.put("4202", "黄石市");
		areaCode.put("4203", "十堰市");
		areaCode.put("4205", "宜昌市");
		areaCode.put("4206", "襄阳市");
		areaCode.put("4207", "鄂州市");
		areaCode.put("4208", "荆门市");
		areaCode.put("4209", "孝感市");
		areaCode.put("4210", "荆州市");
		areaCode.put("4211", "黄冈市");
		areaCode.put("4212", "咸宁市");
		areaCode.put("4213", "随州市");
		areaCode.put("4228", "恩施土家族苗族自治州");
		areaCode.put("4290", "仙桃市");
		areaCode.put("4290", "潜江市");
		areaCode.put("4290", "天门市");
		areaCode.put("4290", "神农架林区");
		areaCode.put("4301", "长沙市");
		areaCode.put("4302", "株洲市");
		areaCode.put("4303", "湘潭市");
		areaCode.put("4304", "衡阳市");
		areaCode.put("4305", "邵阳市");
		areaCode.put("4306", "岳阳市");
		areaCode.put("4307", "常德市");
		areaCode.put("4308", "张家界市");
		areaCode.put("4309", "益阳市");
		areaCode.put("4310", "郴州市");
		areaCode.put("4311", "永州市");
		areaCode.put("4312", "怀化市");
		areaCode.put("4313", "娄底市");
		areaCode.put("4331", "湘西土家族苗族自治州");
		areaCode.put("4401", "广州市");
		areaCode.put("4402", "韶关市");
		areaCode.put("4403", "深圳市");
		areaCode.put("4404", "珠海市");
		areaCode.put("4405", "汕头市");
		areaCode.put("4406", "佛山市");
		areaCode.put("4407", "江门市");
		areaCode.put("4408", "湛江市");
		areaCode.put("4409", "茂名市");
		areaCode.put("4412", "肇庆市");
		areaCode.put("4413", "惠州市");
		areaCode.put("4414", "梅州市");
		areaCode.put("4415", "汕尾市");
		areaCode.put("4416", "河源市");
		areaCode.put("4417", "阳江市");
		areaCode.put("4418", "清远市");
		areaCode.put("4419", "东莞市");
		areaCode.put("4420", "中山市");
		areaCode.put("4451", "潮州市");
		areaCode.put("4452", "揭阳市");
		areaCode.put("4453", "云浮市");
		areaCode.put("4501", "南宁市");
		areaCode.put("4502", "柳州市");
		areaCode.put("4503", "桂林市");
		areaCode.put("4504", "梧州市");
		areaCode.put("4505", "北海市");
		areaCode.put("4506", "防城港市");
		areaCode.put("4507", "钦州市");
		areaCode.put("4508", "贵港市");
		areaCode.put("4509", "玉林市");
		areaCode.put("4510", "百色市");
		areaCode.put("4511", "贺州市");
		areaCode.put("4512", "河池市");
		areaCode.put("4513", "来宾市");
		areaCode.put("4514", "崇左市");
		areaCode.put("4601", "海口市");
		areaCode.put("4602", "三亚市");
		areaCode.put("4603", "三沙市");
		areaCode.put("4604", "儋州市");
		areaCode.put("4690", "五指山市");
		areaCode.put("4690", "琼海市");
		areaCode.put("4690", "文昌市");
		areaCode.put("4690", "万宁市");
		areaCode.put("4690", "东方市");
		areaCode.put("4690", "定安县");
		areaCode.put("4690", "屯昌县");
		areaCode.put("4690", "澄迈县");
		areaCode.put("4690", "临高县");
		areaCode.put("4690", "白沙黎族自治县");
		areaCode.put("4690", "昌江黎族自治县");
		areaCode.put("4690", "乐东黎族自治县");
		areaCode.put("4690", "陵水黎族自治县");
		areaCode.put("4690", "保亭黎族苗族自治县");
		areaCode.put("4690", "琼中黎族苗族自治县");
		areaCode.put("5001", "重庆市");
		areaCode.put("5101", "成都市");
		areaCode.put("5103", "自贡市");
		areaCode.put("5104", "攀枝花市");
		areaCode.put("5105", "泸州市");
		areaCode.put("5106", "德阳市");
		areaCode.put("5107", "绵阳市");
		areaCode.put("5108", "广元市");
		areaCode.put("5109", "遂宁市");
		areaCode.put("5110", "内江市");
		areaCode.put("5111", "乐山市");
		areaCode.put("5113", "南充市");
		areaCode.put("5114", "眉山市");
		areaCode.put("5115", "宜宾市");
		areaCode.put("5116", "广安市");
		areaCode.put("5117", "达州市");
		areaCode.put("5118", "雅安市");
		areaCode.put("5119", "巴中市");
		areaCode.put("5120", "资阳市");
		areaCode.put("5132", "阿坝藏族羌族自治州");
		areaCode.put("5133", "甘孜藏族自治州");
		areaCode.put("5134", "凉山彝族自治州");
		areaCode.put("5201", "贵阳市");
		areaCode.put("5202", "六盘水市");
		areaCode.put("5203", "遵义市");
		areaCode.put("5204", "安顺市");
		areaCode.put("5205", "毕节市");
		areaCode.put("5206", "铜仁市");
		areaCode.put("5223", "黔西南布依族苗族自治州");
		areaCode.put("5226", "黔东南苗族侗族自治州");
		areaCode.put("5227", "黔南布依族苗族自治州");
		areaCode.put("5301", "昆明市");
		areaCode.put("5303", "曲靖市");
		areaCode.put("5304", "玉溪市");
		areaCode.put("5305", "保山市");
		areaCode.put("5306", "昭通市");
		areaCode.put("5307", "丽江市");
		areaCode.put("5308", "普洱市");
		areaCode.put("5309", "临沧市");
		areaCode.put("5323", "楚雄彝族自治州");
		areaCode.put("5325", "红河哈尼族彝族自治州");
		areaCode.put("5326", "文山壮族苗族自治州");
		areaCode.put("5328", "西双版纳傣族自治州");
		areaCode.put("5329", "大理白族自治州");
		areaCode.put("5331", "德宏傣族景颇族自治州");
		areaCode.put("5333", "怒江傈僳族自治州");
		areaCode.put("5334", "迪庆藏族自治州");
		areaCode.put("5401", "拉萨市");
		areaCode.put("5402", "日喀则市");
		areaCode.put("5403", "昌都市");
		areaCode.put("5404", "林芝市");
		areaCode.put("5405", "山南市");
		areaCode.put("5424", "那曲地区");
		areaCode.put("5425", "阿里地区");
		areaCode.put("6101", "西安市");
		areaCode.put("6102", "铜川市");
		areaCode.put("6103", "宝鸡市");
		areaCode.put("6104", "咸阳市");
		areaCode.put("6105", "渭南市");
		areaCode.put("6106", "延安市");
		areaCode.put("6107", "汉中市");
		areaCode.put("6108", "榆林市");
		areaCode.put("6109", "安康市");
		areaCode.put("6110", "商洛市");
		areaCode.put("6201", "兰州市");
		areaCode.put("6202", "嘉峪关市");
		areaCode.put("6203", "金昌市");
		areaCode.put("6204", "白银市");
		areaCode.put("6205", "天水市");
		areaCode.put("6206", "武威市");
		areaCode.put("6207", "张掖市");
		areaCode.put("6208", "平凉市");
		areaCode.put("6209", "酒泉市");
		areaCode.put("6210", "庆阳市");
		areaCode.put("6211", "定西市");
		areaCode.put("6212", "陇南市");
		areaCode.put("6229", "临夏回族自治州");
		areaCode.put("6230", "甘南藏族自治州");
		areaCode.put("6301", "西宁市");
		areaCode.put("6302", "海东市");
		areaCode.put("6322", "海北藏族自治州");
		areaCode.put("6323", "黄南藏族自治州");
		areaCode.put("6325", "海南藏族自治州");
		areaCode.put("6326", "果洛藏族自治州");
		areaCode.put("6327", "玉树藏族自治州");
		areaCode.put("6328", "海西蒙古族藏族自治州");
		areaCode.put("6401", "银川市");
		areaCode.put("6402", "石嘴山市");
		areaCode.put("6403", "吴忠市");
		areaCode.put("6404", "固原市");
		areaCode.put("6405", "中卫市");
		areaCode.put("6501", "乌鲁木齐市");
		areaCode.put("6502", "克拉玛依市");
		areaCode.put("6504", "吐鲁番市");
		areaCode.put("6505", "哈密市");
		areaCode.put("6523", "昌吉回族自治州");
		areaCode.put("6527", "博尔塔拉蒙古自治州");
		areaCode.put("6528", "巴音郭楞蒙古自治州");
		areaCode.put("6529", "阿克苏地区");
		areaCode.put("6530", "克孜勒苏柯尔克孜自治州");
		areaCode.put("6531", "喀什地区");
		areaCode.put("6532", "和田地区");
		areaCode.put("6540", "伊犁哈萨克自治州");
		areaCode.put("6542", "塔城地区");
		areaCode.put("6543", "阿勒泰地区");
		areaCode.put("6590", "石河子市");
		areaCode.put("6590", "阿拉尔市");
		areaCode.put("6590", "图木舒克市");
		areaCode.put("6590", "五家渠市");
		areaCode.put("6590", "北屯市");
		areaCode.put("6590", "铁门关市");
		areaCode.put("6590", "双河市");
		areaCode.put("6590", "可克达拉市");
		areaCode.put("6590", "昆玉市");
//		areaCode.put("7101", "台北市");
//		areaCode.put("7102", "高雄市");
//		areaCode.put("7103", "基隆市");
//		areaCode.put("7104", "台中市");
//		areaCode.put("7105", "台南市");
//		areaCode.put("7106", "新竹市");
//		areaCode.put("7107", "嘉义市");
//		areaCode.put("7108", "新北市");
//		areaCode.put("7122", "宜兰县");
//		areaCode.put("7123", "桃园市");
//		areaCode.put("7124", "新竹县");
//		areaCode.put("7125", "苗栗县");
//		areaCode.put("7127", "彰化县");
//		areaCode.put("7128", "南投县");
//		areaCode.put("7129", "云林县");
//		areaCode.put("7130", "嘉义县");
//		areaCode.put("7133", "屏东县");
//		areaCode.put("7134", "台东县");
//		areaCode.put("7135", "花莲县");
//		areaCode.put("7136", "澎湖县");
//		areaCode.put("7137", "金门县");
//		areaCode.put("7138", "连江县");
//		areaCode.put("8101", "香港岛");
//		areaCode.put("8102", "九龙");
//		areaCode.put("8103", "新界");
//		areaCode.put("8201", "澳门半岛");
//		areaCode.put("8202", "氹仔岛");
//		areaCode.put("8203", "路环岛");
		return areaCode;
	}
	
	
}